package com.keqiang.chart.impl.pie.impl.normal

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import com.keqiang.chart.animation.Animator
import com.keqiang.chart.impl.pie.render.BaseDataRender
import com.keqiang.chart.utils.ObjectPool
import com.keqiang.chart.utils.drawArc

/**
 * 饼状图数据绘制器
 *
 * @author Created by wanggaowan on 2022/8/30 16:30
 */
open class PieChartDataRender(chart: PieChart) : BaseDataRender<PieChart>(chart) {

    override fun onDraw(canvas: Canvas, startAngle: Float) {
        val paint = ObjectPool.obtainPaint<Paint>()
        val (centerX, centerY) = chart.getCenter()
        drawBg(canvas, paint, centerX, centerY)

        if (chart.data.isNullOrEmpty()) {
            ObjectPool.recyclePaint(paint)
            return
        }

        var totalValue = 0f
        val dataList = mutableListOf<PieEntity>()
        chart.data?.let {
            dataList.addAll(it)
        }

        dataList.forEach {
            if (it.isDraw && it.value > 0) {
                totalValue += it.value
            }
        }

        drawData(canvas, paint, centerX, centerY, totalValue, startAngle, dataList, chart.animator)
        ObjectPool.recyclePaint(paint)
    }

    /**
     * 绘制数据内容
     */
    protected open fun drawData(canvas: Canvas, paint: Paint, centerX: Float, centerY: Float, totalValue: Float, startAngle: Float,
                         dataList: List<PieEntity>, animator: Animator?) {
        paint.style = Paint.Style.FILL
        val animProgress = animator?.getProgress() ?: 1f
        val touchData = chart.touchHandler?.touchData
        val highLightRender = chart.highLightRender
        val tempRectF = ObjectPool.obtainRectF()

        // 偏移角度，也是当前需要绘制扇形的起始角度
        var offsetDegrees = startAngle
        val sliceSpace = if (dataList.size == 1) 0f else chart.sliceSpace
        for (index in dataList.indices) {
            val data = dataList[index]
            if (!data.isDraw) {
                continue
            }

            val degrees = if (totalValue == 0f) 0f else data.value / totalValue * 360 * animProgress
            data.drawStartAngle = offsetDegrees
            data.drawSweepAngle = degrees

            if (touchData == data && highLightRender != null) {
                data.drawRadius = highLightRender.getRadius(data)
                val (dx, dy) = highLightRender.getOffset(data)
                data.offsetDx = dx
                data.offsetDy = dy
                if (data.drawSweepAngle > 0) {
                    highLightRender.onDraw(canvas, offsetDegrees, degrees, data)
                }
            } else {
                data.drawRadius = chart.radius + data.addedRadius
                data.offsetDx = 0f
                data.offsetDy = 0f
                if (data.drawSweepAngle > 0) {
                    canvas.drawArc(paint, centerX, centerY, data.drawRadius, chart.innerRadius, data.drawStartAngle, data.drawSweepAngle, data.color,
                        data.offsetDx, data.offsetDy, sliceSpace)
                }
            }

            offsetDegrees += degrees
        }

        ObjectPool.recycleRectF(tempRectF)
    }

    protected open fun drawBg(canvas: Canvas, paint: Paint, centerX: Float, centerY: Float) {
        val alpha = Color.alpha(chart.baseMapColor)
        if (alpha == 0) {
            return
        }

        canvas.drawArc(paint, centerX, centerY, chart.radius, chart.innerRadius, 0f, 360f, chart.baseMapColor)
    }
}